package org.dromara.system.service.impl;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import org.apache.poi.ss.formula.functions.T;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.dromara.system.domain.*;
import org.dromara.system.domain.bo.*;
import org.dromara.system.domain.vo.*;
import org.dromara.system.mapper.*;
import org.dromara.system.utils.SkyEyeClientUtil;
import org.dromara.system.utils.SkyEyeProperties;
import org.springframework.stereotype.Service;
import org.dromara.system.service.ISkyBagService;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 项目分包Service业务层处理
 *
 * @author Lion Li
 * @date 2024-09-24
 */
@RequiredArgsConstructor
@Service
public class SkyBagServiceImpl implements ISkyBagService {

    private final SkyBagMapper baseMapper;
    private final SkyNodeMapper nodeMapper;
    private final SkyRelationshipMapper relationshipMapper;
    private final WbCompanyInfoMapper companyInfoMapper;
    private final WbCandidateListMapper candidateListMapper;

    /**
     * 查询项目分包
     */
    @Override
    public SkyBagVo queryById(String id){
        return baseMapper.selectVoById(id);
    }

    /**
     * 查询项目分包列表
     */
    @Override
    public TableDataInfo<SkyBagVo> queryPageList(SkyBagBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<SkyBag> lqw = buildQueryWrapper(bo);
        Page<SkyBagVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    private LambdaQueryWrapper<SkyBag> buildQueryWrapper(SkyBagBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<SkyBag> lqw = Wrappers.lambdaQuery();
        lqw.like(StringUtils.isNotBlank(bo.getName()), SkyBag::getName, bo.getName());
        lqw.like(StringUtils.isNotBlank(bo.getCompaniesName()), SkyBag::getCompaniesName, bo.getCompaniesName());
        lqw.eq(StringUtils.isNotBlank(bo.getCompaniesCode()), SkyBag::getCompaniesCode, bo.getCompaniesCode());
        lqw.eq(bo.getCandidateId() != null, SkyBag::getCandidateId, bo.getCandidateId());
        return lqw;
    }

    /**
     * 新增项目分包
     */
    @Override
    public Boolean insertByBo(SkyBagBo bo) {
        SkyBag add = MapstructUtils.convert(bo, SkyBag.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改项目分包
     */
    @Override
    public Boolean updateByBo(SkyBagBo bo) {
        SkyBag update = MapstructUtils.convert(bo, SkyBag.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(SkyBag entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除项目分包
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<String> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    @Override
    public void mergeDataByCandidate(String candidate) {
        //根据candidate查询数据
        ArchivesBo bo = new ArchivesBo();
            bo.setKeyword(candidate);

        JSONObject data = SkyEyeClientUtil.query(bo, SkyEyeProperties.COMPANY_FACE);

        if(data != null && !data.isEmpty()) {
            saveRelations(data.getJSONArray("relationships"));
            saveNodes(data.getJSONArray("nodes"));
        }
    }

    private void saveRelations(JSONArray relationships) {
        List<SkyRelationship> list = new ArrayList<>();

        for(int j = 0; j < relationships.size(); j++) {
            JSONObject relationship = relationships.getJSONObject(j);
            JSONObject properties = relationship.getJSONObject("properties");

            SkyRelationship skyRelationship = new SkyRelationship();
                skyRelationship.setId(Long.parseLong(relationship.getStr("id")));
                skyRelationship.setStartNode(relationship.getStr("startNode"));
                skyRelationship.setEndNode(relationship.getStr("endNode"));
                skyRelationship.setDataType(relationship.getStr("type"));
                skyRelationship.setName(getLabelString(properties.getJSONArray("labels")));
                skyRelationship.setPercent(properties.getStr("percent"));

            list.add(skyRelationship);
        }

        relationshipMapper.insertOrUpdateBatch(list);
    }

    private void saveNodes(JSONArray nodes) {
        List<SkyNode> list = new ArrayList<>();
        //node存储
        for (int j = 0; j < nodes.size(); j++) {
            JSONObject node = nodes.getJSONObject(j);
            JSONObject properties = node.getJSONObject("properties");

            SkyNode skyNode = new SkyNode();
                skyNode.setId(Long.parseLong(node.getStr("id")));
                skyNode.setCode(node.getStr("id"));
                skyNode.setName(properties.getStr("name"));
                skyNode.setLogoUrl(properties.getStr("logo"));
                skyNode.setDataType(getLabelString(node.getJSONArray("labels")));

            list.add(skyNode);
        }

        nodeMapper.insertOrUpdateBatch(list);
    }

    @Override
    public void mergeDataByCandidate(Long candidateId) {
//        //查询需要带出所有包信息
//        List<WbCandidateList> list = candidateListMapper.selectList(new LambdaQueryWrapper<WbCandidateList>().eq(true, WbCandidateList::getCandidateId, candidateId));
//        //根据包名进行分组
//        Map<String, List<WbCandidateList>> map = list.stream().collect(Collectors.groupingBy(WbCandidateList::getBagName));
//        //对每个包进行查询
//        for (String bagName : map.keySet()) {
//            deal(bagName, candidateId, list);
//        }
    }

//    /**
//     * 处理
//     * @param bagName 包名
//     * @param candidateId 项目ID
//     * @param list 包列表
//     */
//    private void deal(String bagName, Long candidateId, List<WbCandidateList> list) {
//        //测试阶段只允许查询小于20家公司
//        String uuidStr;
//        Long bagId;
//        String companyNames = list.stream().limit(20).toList().stream().map(WbCandidateList::getCandidate).collect(Collectors.joining(","));
//        SkyBag skyBag = baseMapper.selectOne(new LambdaQueryWrapper<SkyBag>()
//            .eq(true, SkyBag::getCandidateId, candidateId)
//            .eq(true, SkyBag::getName, bagName)
//            .eq(true, SkyBag::getCompaniesName, companyNames));
//
//        if(skyBag == null) {
//            UUID uuid = UUID.randomUUID();
//            uuidStr = uuid.toString().replace("-", "").toUpperCase();
//            bagId = saveBag(candidateId, bagName, uuidStr, companyNames);
//        } else {
//            uuidStr = skyBag.getUuid();
//            bagId = skyBag.getId();
//        }
//
//        ArchivesBo bo = new ArchivesBo();
//            bo.setCompanyNames(companyNames);
//            bo.setDepth("2");
//            bo.setTypes("ALL");
//            bo.setUuid(uuidStr);
//        JSONObject jsonMap = SkyEyeClientUtil.queryByLoopForBid(bo, SkyEyeProperties.RELA_HIDDEN);
//
//        for (String key : jsonMap.keySet()){
//            //查找关系图
//            if(!key.contains("p_")) {
//                continue;
//            }
//
//            JSONObject p = jsonMap.getJSONObject(key);
//            saveNode(p.containsKey("nodes") ? p.getJSONArray("nodes") : new JSONArray());
//            saveRelationship(bagId, p.containsKey("relationships") ? p.getJSONArray("relationships") : new JSONArray());
//        }
//    }

    /**
     * 保存分包数据
     * @param candidateId 项目ID
     * @param companyNames 公司名称
     */
    private Long saveBag(Long candidateId, String bagName, String uuid, String companyNames) {
        //判断包是否存在
        SkyBagBo bo = new SkyBagBo();
            bo.setCandidateId(candidateId);
            bo.setName(bagName);
            bo.setCompaniesName(companyNames);
            bo.setUuid(uuid);

        insertByBo(bo);
        return bo.getId();
    }

    /**
     * 保存分包节点
     * @param nodes 节点
     */
    private void saveNode(JSONArray nodes) {
        List<SkyNode> list = new ArrayList<>();
        //node存储
        for (int j = 0; j < nodes.size(); j++) {
            JSONObject node = nodes.getJSONObject(j);
            JSONObject properties = node.getJSONObject("properties");

            SkyNode skyNode = new SkyNode();
                skyNode.setId(Long.parseLong(node.containsKey("idNew") ? node.getStr("idNew") : node.getStr("id")));
                skyNode.setCode(node.containsKey("idNew") ? node.getStr("idNew") : node.getStr("id"));
                skyNode.setName(properties.getStr("name"));
                skyNode.setRegStatus(node.getStr("regStatus"));
                skyNode.setDataType(getLabelString(node.getJSONArray("labels")));

            //因为需要更新企业信息，此处更新方法启用
            //saveCompany(skyNode);
            list.add(skyNode);
        }

        nodeMapper.insertOrUpdateBatch(list);
    }

    /**
     * 保存分包关系
     * @param relationships 关系
     */
    private void saveRelationship(Long bagId, JSONArray relationships) {
        List<SkyRelationship> list = new ArrayList<>();

        for(int j = 0; j < relationships.size(); j++) {
            JSONObject relationship = relationships.getJSONObject(j);
            JSONObject properties = relationship.getJSONObject("properties");

            SkyRelationship skyRelationship = new SkyRelationship();
                skyRelationship.setStartNode(relationship.containsKey("startNodeNew") ? relationship.getStr("startNodeNew") : relationship.getStr("startNode"));
                skyRelationship.setEndNode(relationship.containsKey("endNodeNew") ? relationship.getStr("endNodeNew") : relationship.getStr("endNode"));
                skyRelationship.setDataType(relationship.getStr("type"));
                skyRelationship.setName(getLabelString(properties.getJSONArray("labels")));
                skyRelationship.setPercent(properties.getStr("percent"));
                skyRelationship.setBagId(bagId);

            list.add(skyRelationship);
        }

        relationshipMapper.delete(new LambdaQueryWrapper<SkyRelationship>().eq(true, SkyRelationship::getBagId, bagId));
        relationshipMapper.insertBatch(list);
    }

    /**
     * 更新公司信息
     * @param skyNode 天眼查节点
     */
    private void saveCompany(SkyNode skyNode) {
        List<WbCompanyInfoVo> companyList = companyInfoMapper.selectVoList(new LambdaQueryWrapper<WbCompanyInfo>().eq(true, WbCompanyInfo::getName, skyNode.getName()));

        if(!companyList.isEmpty()) {
            WbCompanyInfoVo vo = companyList.get(0);
            WbCompanyInfo bo = new WbCompanyInfo();
                bo.setId(vo.getId());
                bo.setSkyId(skyNode.getId());
                bo.setRegStatus(skyNode.getRegStatus());
            companyInfoMapper.updateById(bo);
        } else {
            WbCompanyInfoBo bo = new WbCompanyInfoBo();
                bo.setName(skyNode.getName());
                bo.setSkyId(skyNode.getId());
                bo.setRegStatus(skyNode.getRegStatus());
            WbCompanyInfo add = MapstructUtils.convert(bo, WbCompanyInfo.class);
            companyInfoMapper.insert(add);
        }
    }

    /**
     * 获取数组
     * @param labels 标签
     * @return 标签字符串
     */
    private static String getLabelString(JSONArray labels) {
        if(labels == null || labels.isEmpty()) {
            return "";
        }

        StringBuilder sb = new StringBuilder();

        for (Object label : labels) {
            if (!sb.isEmpty()) {
                sb.append(",");
            }

            sb.append(label.toString());
        }

        return sb.toString();
    }

    private List<SkyRelationshipVo> changeRelation(WbCandidateListVo vo, List<SkyRelationshipVo> childList) {
//        childList.stream().map(data -> {
//            data.setBagName(vo.getBagName());
//            data.setSubStandardName(vo.getSubStandardName());
//            return data;
//        }).toList();

//数据分为两个值
        //第一个值作为ID，
        Map<String, SkyRelationshipVo> map = new HashMap<>();

        for(SkyRelationshipVo relationshipVo : childList) {
            if (map.isEmpty()) {
                map.put(relationshipVo.getStartNode(), relationshipVo);
            }
        }

        List<String> needDelete = new ArrayList<>();

        for(String key : map.keySet()) {
            SkyRelationshipVo data = map.get(key);
            SkyRelationshipVo child = map.get(data.getStartNode());
            List<SkyRelationshipVo> childVoList = data.getChildList()==null?new ArrayList<>():data.getChildList();
                childVoList.add(child);
            data.setChildList(childVoList);
            //设置了节点后，需要去除该节点
            needDelete.add(child.getStartNode());
        }

        for(String key : map.keySet()) {
            SkyRelationshipVo data = map.get(key);
            data.setRelation(map.get(data.getStartNode()));
        }

        return childList.stream().map(data -> {
            data.setBagName(vo.getBagName());
            data.setSubStandardName(vo.getSubStandardName());
            return data;
        }).toList();
    }
}
